package org.springframework.data.elasticsearch.core.convert; /**
 * @author zhao.xin06679
 * @date 2021年07月05日 16:12
 */


import com.google.gson.Gson;
import org.springframework.data.convert.DefaultTypeMapper;
import org.springframework.data.convert.SimpleTypeInformationMapper;
import org.springframework.data.convert.TypeAliasAccessor;
import org.springframework.data.convert.TypeInformationMapper;
import org.springframework.data.mapping.Alias;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.lang.Nullable;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class DefaultElasticsearchTypeMapper extends DefaultTypeMapper<Map<String, Object>> implements ElasticsearchTypeMapper {
    @Nullable
    private final String typeKey;

    public DefaultElasticsearchTypeMapper(@Nullable String typeKey) {
        this(typeKey, Collections.singletonList(new SimpleTypeInformationMapper()));
    }

    public DefaultElasticsearchTypeMapper(@Nullable String typeKey, MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext) {
        this(typeKey, new DefaultElasticsearchTypeMapper.MapTypeAliasAccessor(typeKey), mappingContext, Collections.singletonList(new SimpleTypeInformationMapper()));
    }

    public DefaultElasticsearchTypeMapper(@Nullable String typeKey, List<? extends TypeInformationMapper> mappers) {
        this(typeKey, new DefaultElasticsearchTypeMapper.MapTypeAliasAccessor(typeKey), (MappingContext)null, mappers);
    }

    public DefaultElasticsearchTypeMapper(@Nullable String typeKey, TypeAliasAccessor<Map<String, Object>> accessor, @Nullable MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext, List<? extends TypeInformationMapper> mappers) {
        super(accessor, mappingContext, mappers);
        this.typeKey = typeKey;
    }

    public boolean isTypeKey(String key) {
        return this.typeKey != null && this.typeKey.equals(key);
    }

    public static class MapTypeAliasAccessor implements TypeAliasAccessor<Map<String, Object>> {
        @Nullable
        private final String typeKey;

        public MapTypeAliasAccessor(@Nullable String typeKey) {
            this.typeKey = typeKey;
        }

        public Alias readAliasFrom(Map<String, Object> source) {
            return Alias.ofNullable(source.get(this.typeKey));
        }

        public void writeTypeTo(Map<String, Object> sink, Object alias) {
            Gson g = new Gson();
            System.out.println(g.toJson(sink));
            System.out.println(g.toJson(alias));
        }
    }
}

